package cn.jingyuan.bee.utils.collection;

import cn.jingyuan.bee.utils.*;
import cn.jingyuan.bee.utils.bean.BeanUtils;
import cn.jingyuan.bee.utils.comparator.PinyinComparator;
import cn.jingyuan.bee.utils.comparator.PropertyComparator;
import cn.jingyuan.bee.utils.convert.Convert;
import cn.jingyuan.bee.utils.convert.ConverterRegistry;
import cn.jingyuan.bee.utils.exceptions.UtilsException;
import cn.jingyuan.bee.utils.lang.Editor;
import cn.jingyuan.bee.utils.lang.Filter;
import cn.jingyuan.bee.utils.lang.Matcher;
import cn.jingyuan.bee.utils.map.MapUtils;

import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 集合相关工具类
 *
 * <p>
 * 此工具方法针对 {@link Collection} 及其实现类封装的工具
 * <p>
 * <p>
 * 由于 {@link Collection} 实现了 {@link Iterable} 接口，因此部分工具此类不提供，而是在 {@link IterUtils} 中提供
 */
public class CollectionUtils {

    /**
     * 如果提供的集合为 {@code null}，返回一个不可变的默认空集合，否则返回原集合<br>
     * 空集合使用 {@link Collections#emptySet()}
     *
     * @param <T> 集合元素类型
     * @param set 提供的集合，可能为 null
     *
     * @return 原集合，若为 null 返回空集合
     */
    public static <T> Set<T> emptyIfNull(Set<T> set) {
        return (null == set) ? Collections.emptySet() : set;
    }

    /**
     * 如果提供的集合为 {@code null}，返回一个不可变的默认空集合，否则返回原集合<br>
     * 空集合使用 {@link Collections#emptyList()}
     *
     * @param <T> 集合元素类型
     * @param set 提供的集合，可能为 null
     *
     * @return 原集合，若为 null 返回空集合
     */
    public static <T> List<T> emptyIfNull(List<T> set) {
        return (null == set) ? Collections.emptyList() : set;
    }

    /**
     * 两个集合的并集<br>
     * 针对一个集合中存在多个相同元素的情况，计算两个集合中此元素的个数，保留最多的个数<br>
     * 例如：集合1：[a, b, c, c, c]，集合2：[a, b, c, c]<br>
     * 结果：[a, b, c, c, c]，此结果中只保留了三个 c
     *
     * @param <T> 集合元素类型
     * @param collection1 集合1
     * @param collection2 集合2
     *
     * @return 并集的集合，返回 {@link ArrayList}
     */
    public static <T> Collection<T> union(Collection<T> collection1, Collection<T> collection2) {
        final ArrayList<T> list = new ArrayList<>();
        if (isEmpty(collection1)) {
            list.addAll(collection2);
        } else if (isEmpty(collection2)) {
            list.addAll(collection1);
        } else {
            final Map<T, Integer> map1 = countMap(collection1);
            final Map<T, Integer> map2 = countMap(collection2);
            final Set<T> hashSet = newHashSet(collection2);
            hashSet.addAll(collection1);
            int m;
            for (T t : hashSet) {
                m = Math.max(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
                for (int i = 0; i < m; i++) {
                    list.add(t);
                }
            }
        }
        return list;
    }

    /**
     * 多个集合的并集<br>
     * 针对一个集合中存在多个相同元素的情况，计算两个集合中此元素的个数，保留最多的个数<br>
     * 例如：集合1：[a, b, c, c, c]，集合2：[a, b, c, c]<br>
     * 结果：[a, b, c, c, c]，此结果中只保留了三个 c
     *
     * @param <T> 集合元素类型
     * @param collection1 集合1
     * @param collection2 集合2
     * @param otherCollections 其它集合
     *
     * @return 并集的集合，返回 {@link ArrayList}
     */
    @SafeVarargs
    public static <T> Collection<T> union(Collection<T> collection1, Collection<T> collection2, Collection<T>... otherCollections) {
        Collection<T> union = union(collection1, collection2);
        for (Collection<T> coll : otherCollections) {
            union = union(union, coll);
        }
        return union;
    }

    /**
     * 两个集合的交集<br>
     * 针对一个集合中存在多个相同元素的情况，计算两个集合中此元素的个数，保留最少的个数<br>
     * 例如：集合1：[a, b, c, c, c]，集合2：[a, b, c, c]<br>
     * 结果：[a, b, c, c]，此结果中只保留了两个 c
     *
     * @param <T> 集合元素类型
     * @param collection1 集合1
     * @param collection2 集合2
     *
     * @return 交集的集合，返回 {@link ArrayList}
     */
    public static <T> Collection<T> intersection(Collection<T> collection1, Collection<T> collection2) {
        final ArrayList<T> list = new ArrayList<>();
        if (isNotEmpty(collection1) && isNotEmpty(collection2)) {
            final Map<T, Integer> map1 = countMap(collection1);
            final Map<T, Integer> map2 = countMap(collection2);
            final Set<T> elts = newHashSet(collection2);
            int m;
            for (T t : elts) {
                m = Math.min(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
                for (int i = 0; i < m; i++) {
                    list.add(t);
                }
            }
        }
        return list;
    }

    /**
     * 多个集合的交集<br>
     * 针对一个集合中存在多个相同元素的情况，计算两个集合中此元素的个数，保留最少的个数<br>
     * 例如：集合1：[a, b, c, c, c]，集合2：[a, b, c, c]<br>
     * 结果：[a, b, c, c]，此结果中只保留了两个 c
     *
     * @param <T> 集合元素类型
     * @param collection1 集合1
     * @param collection2 集合2
     * @param otherCollections 其它集合
     *
     * @return 并集的集合，返回 {@link ArrayList}
     */
    @SafeVarargs
    public static <T> Collection<T> intersection(Collection<T> collection1, Collection<T> collection2, Collection<T>... otherCollections) {
        Collection<T> intersection = intersection(collection1, collection2);
        if (isEmpty(intersection)) {
            return intersection;
        }
        for (Collection<T> coll : otherCollections) {
            intersection = intersection(intersection, coll);
            if (isEmpty(intersection)) {
                return intersection;
            }
        }
        return intersection;
    }

    /**
     * 两个集合的差集<br>
     * 针对一个集合中存在多个相同元素的情况，计算两个集合中此元素的个数，保留两个集合中此元素个数差的个数<br>
     * 例如：集合1：[a, b, c, c, c]，集合2：[a, b, c, c]<br>
     * 结果：[c]，此结果中只保留了一个<br>
     * 任意一个集合为空，返回另一个集合<br>
     * 两个集合无差集则返回空集合
     *
     * @param <T> 集合元素类型
     * @param collection1 集合1
     * @param collection2 集合2
     *
     * @return 差集的集合，返回 {@link ArrayList}
     */
    public static <T> Collection<T> disjunction(Collection<T> collection1, Collection<T> collection2) {
        if (isEmpty(collection1)) {
            return collection2;
        }
        if (isEmpty(collection2)) {
            return collection1;
        }

        final ArrayList<T> result = new ArrayList<>();
        final Map<T, Integer> map1 = countMap(collection1);
        final Map<T, Integer> map2 = countMap(collection2);
        final Set<T> elts = newHashSet(collection2);
        elts.addAll(collection1);
        int m;
        for (T t : elts) {
            m = Math.abs(Convert.toInt(map1.get(t), 0) - Convert.toInt(map2.get(t), 0));
            for (int i = 0; i < m; i++) {
                result.add(t);
            }
        }
        return result;
    }

    /**
     * 判断指定集合是否包含指定值，如果集合为空（null 或者空），返回 {@code false}，否则找到元素返回 {@code true}
     *
     * @param collection 集合
     * @param value 需要查找的值
     *
     * @return 如果集合为空（null 或者空），返回 {@code false}，否则找到元素返回 {@code true}
     */
    public static boolean contains(Collection<?> collection, Object value) {
        return isNotEmpty(collection) && collection.contains(value);
    }

    /**
     * 其中一个集合在另一个集合中是否至少包含一个元素，即是两个集合是否至少有一个共同的元素
     *
     * @param collection1 集合1
     * @param collection2 集合2
     *
     * @return 其中一个集合在另一个集合中是否至少包含一个元素
     *
     * @see #intersection
     */
    public static boolean containsAny(Collection<?> collection1, Collection<?> collection2) {
        if (isEmpty(collection1) || isEmpty(collection2)) {
            return false;
        }
        if (collection1.size() < collection2.size()) {
            for (Object object : collection1) {
                if (collection2.contains(object)) {
                    return true;
                }
            }
        } else {
            for (Object object : collection2) {
                if (collection1.contains(object)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 集合1 中是否包含集合2 中所有的元素，即集合2 是否为集合1 的子集
     *
     * @param collection1 集合1
     * @param collection2 集合2
     *
     * @return 集合1 中是否包含集合2 中所有的元素
     */
    public static boolean containsAll(Collection<?> collection1, Collection<?> collection2) {
        if (isEmpty(collection1) || isEmpty(collection2) || collection1.size() < collection2.size()) {
            return false;
        }

        for (Object object : collection2) {
            if (!collection1.contains(object)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 根据集合返回一个元素计数的 {@link Map}<br>
     * 所谓元素计数就是假如这个集合中某个元素出现了 n 次，那将这个元素做为 key，n 做为 value<br>
     * 例如：[a,b,c,c,c] 得到：<br>
     * a: 1<br>
     * b: 1<br>
     * c: 3<br>
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     *
     * @return {@link Map}
     *
     * @see IterUtils#countMap(Iterable)
     */
    public static <T> Map<T, Integer> countMap(Iterable<T> collection) {
        return IterUtils.countMap(collection);
    }

    /**
     * 以 conjunction 为分隔符将集合转换为字符串<br>
     * 如果集合元素为数组、{@link Iterable} 或 {@link Iterator}，则递归组合其为字符串
     *
     * @param <T> 集合元素类型
     * @param iterable {@link Iterable}
     * @param conjunction 分隔符
     *
     * @return 连接后的字符串
     *
     * @see IterUtils#join(Iterable, CharSequence)
     */
    public static <T> String join(Iterable<T> iterable, CharSequence conjunction) {
        return IterUtils.join(iterable, conjunction);
    }

    /**
     * 以 conjunction 为分隔符将集合转换为字符串<br>
     * 如果集合元素为数组、{@link Iterable} 或 {@link Iterator}，则递归组合其为字符串
     *
     * @param <T> 集合元素类型
     * @param iterator 集合
     * @param conjunction 分隔符
     *
     * @return 连接后的字符串
     *
     * @see IterUtils#join(Iterator, CharSequence)
     */
    public static <T> String join(Iterator<T> iterator, CharSequence conjunction) {
        return IterUtils.join(iterator, conjunction);
    }

    /**
     * 切取部分数据<br>
     * 切取后的栈将减少这些元素
     *
     * @param <T> 集合元素类型
     * @param surplusAlaData 原数据
     * @param partSize 每部分数据的长度
     *
     * @return 切取出的数据或 null
     */
    public static <T> List<T> popPart(Stack<T> surplusAlaData, int partSize) {
        if (isEmpty(surplusAlaData)) {
            return null;
        }

        final List<T> currentAlaDatas = new ArrayList<>();
        int size = surplusAlaData.size();
        // 切割
        if (size > partSize) {
            for (int i = 0; i < partSize; i++) {
                currentAlaDatas.add(surplusAlaData.pop());
            }
        } else {
            for (int i = 0; i < size; i++) {
                currentAlaDatas.add(surplusAlaData.pop());
            }
        }
        return currentAlaDatas;
    }

    /**
     * 切取部分数据<br>
     * 切取后的栈将减少这些元素
     *
     * @param <T> 集合元素类型
     * @param surplusAlaData 原数据
     * @param partSize 每部分数据的长度
     *
     * @return 切取出的数据或 null
     */
    public static <T> List<T> popPart(Deque<T> surplusAlaData, int partSize) {
        if (isEmpty(surplusAlaData)) {
            return null;
        }

        final List<T> currentAlaDatas = new ArrayList<>();
        int size = surplusAlaData.size();
        // 切割
        if (size > partSize) {
            for (int i = 0; i < partSize; i++) {
                currentAlaDatas.add(surplusAlaData.pop());
            }
        } else {
            for (int i = 0; i < size; i++) {
                currentAlaDatas.add(surplusAlaData.pop());
            }
        }
        return currentAlaDatas;
    }

    /**
     * 新建一个 HashMap
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     *
     * @return HashMap 对象
     *
     * @see MapUtils#newHashMap()
     */
    public static <K, V> HashMap<K, V> newHashMap() {
        return MapUtils.newHashMap();
    }

    /**
     * 新建一个 HashMap
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     * @param size 初始大小，由于默认负载因子 0.75，传入的 size 会实际初始大小为 size / 0.75
     * @param isOrder Map 的 Key 是否有序，有序返回 {@link LinkedHashMap}，否则返回 {@link HashMap}
     *
     * @return HashMap 对象
     *
     * @see MapUtils#newHashMap(int, boolean)
     */
    public static <K, V> HashMap<K, V> newHashMap(int size, boolean isOrder) {
        return MapUtils.newHashMap(size, isOrder);
    }

    /**
     * 新建一个 HashMap
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     * @param size 初始大小，由于默认负载因子 0.75，传入的 size 会实际初始大小为 size / 0.75
     *
     * @return HashMap 对象
     *
     * @see MapUtils#newHashMap(int)
     */
    public static <K, V> HashMap<K, V> newHashMap(int size) {
        return MapUtils.newHashMap(size);
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param ts 元素数组
     *
     * @return HashSet 对象
     */
    @SafeVarargs
    public static <T> HashSet<T> newHashSet(T... ts) {
        return newHashSet(false, ts);
    }

    /**
     * 新建一个 LinkedHashSet
     *
     * @param <T> 集合元素类型
     * @param ts 元素数组
     *
     * @return HashSet 对象
     */
    @SafeVarargs
    public static <T> LinkedHashSet<T> newLinkedHashSet(T... ts) {
        return (LinkedHashSet<T>) newHashSet(true, ts);
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param isSorted 是否有序，有序返回 {@link LinkedHashSet}，否则返回 {@link HashSet}
     * @param ts 元素数组
     *
     * @return HashSet 对象
     */
    @SafeVarargs
    public static <T> HashSet<T> newHashSet(boolean isSorted, T... ts) {
        if (null == ts) {
            return isSorted ? new LinkedHashSet<>() : new HashSet<>();
        }
        int initialCapacity = Math.max((int) (ts.length / .75f) + 1, 16);
        final HashSet<T> set = isSorted ? new LinkedHashSet<>(initialCapacity) : new HashSet<>(initialCapacity);
        Collections.addAll(set, ts);
        return set;
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     *
     * @return HashSet 对象
     */
    public static <T> HashSet<T> newHashSet(Collection<T> collection) {
        return newHashSet(false, collection);
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param isSorted 是否有序，有序返回 {@link LinkedHashSet}，否则返回 {@link HashSet}
     * @param collection 集合，用于初始化 Set
     *
     * @return HashSet 对象
     */
    public static <T> HashSet<T> newHashSet(boolean isSorted, Collection<T> collection) {
        return isSorted ? new LinkedHashSet<>(collection) : new HashSet<>(collection);
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param isSorted 是否有序，有序返回 {@link LinkedHashSet}，否则返回 {@link HashSet}
     * @param iter {@link Iterator}
     *
     * @return HashSet 对象
     */
    public static <T> HashSet<T> newHashSet(boolean isSorted, Iterator<T> iter) {
        if (null == iter) {
            return newHashSet(isSorted, (T[]) null);
        }
        final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
        while (iter.hasNext()) {
            set.add(iter.next());
        }
        return set;
    }

    /**
     * 新建一个 HashSet
     *
     * @param <T> 集合元素类型
     * @param isSorted 是否有序，有序返回 {@link LinkedHashSet}，否则返回 {@link HashSet}
     * @param enumeration {@link Enumeration}
     *
     * @return HashSet 对象
     */
    public static <T> HashSet<T> newHashSet(boolean isSorted, Enumeration<T> enumeration) {
        if (null == enumeration) {
            return newHashSet(isSorted, (T[]) null);
        }
        final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
        while (enumeration.hasMoreElements()) {
            set.add(enumeration.nextElement());
        }
        return set;
    }

    /**
     * 新建一个空 List
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     *
     * @return List 对象
     */
    public static <T> List<T> list(boolean isLinked) {
        return isLinked ? new LinkedList<>() : new ArrayList<>();
    }

    /**
     * 新建一个 List
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     * @param values 数组
     *
     * @return List 对象
     */
    @SafeVarargs
    public static <T> List<T> list(boolean isLinked, T... values) {
        if (ArrayUtils.isEmpty(values)) {
            return list(isLinked);
        }
        final List<T> arrayList = isLinked ? new LinkedList<>() : new ArrayList<>(values.length);
        Collections.addAll(arrayList, values);
        return arrayList;
    }

    /**
     * 新建一个 List
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     * @param collection 集合
     *
     * @return List 对象
     */
    public static <T> List<T> list(boolean isLinked, Collection<T> collection) {
        if (null == collection) {
            return list(isLinked);
        }
        return isLinked ? new LinkedList<>(collection) : new ArrayList<>(collection);
    }

    /**
     * 新建一个 List<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     * @param iterable {@link Iterable}
     *
     * @return List 对象
     */
    public static <T> List<T> list(boolean isLinked, Iterable<T> iterable) {
        if (null == iterable) {
            return list(isLinked);
        }
        return list(isLinked, iterable.iterator());
    }

    /**
     * 新建一个 ArrayList<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     * @param iter {@link Iterator}
     *
     * @return ArrayList 对象
     */
    public static <T> List<T> list(boolean isLinked, Iterator<T> iter) {
        final List<T> list = list(isLinked);
        if (null != iter) {
            while (iter.hasNext()) {
                list.add(iter.next());
            }
        }
        return list;
    }

    /**
     * 新建一个 List<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param isLinked 是否新建 LinkedList
     * @param enumeration {@link Enumeration}
     *
     * @return ArrayList 对象
     */
    public static <T> List<T> list(boolean isLinked, Enumeration<T> enumeration) {
        final List<T> list = list(isLinked);
        if (null != enumeration) {
            while (enumeration.hasMoreElements()) {
                list.add(enumeration.nextElement());
            }
        }
        return list;
    }

    /**
     * 新建一个 ArrayList
     *
     * @param <T> 集合元素类型
     * @param values 数组
     *
     * @return ArrayList 对象
     */
    @SafeVarargs
    public static <T> ArrayList<T> newArrayList(T... values) {
        return (ArrayList<T>) list(false, values);
    }

    /**
     * 数组转为 ArrayList
     *
     * @param <T> 集合元素类型
     * @param values 数组
     *
     * @return ArrayList 对象
     */
    @SafeVarargs
    public static <T> ArrayList<T> toList(T... values) {
        return newArrayList(values);
    }

    /**
     * 新建一个 ArrayList
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     *
     * @return ArrayList 对象
     */
    public static <T> ArrayList<T> newArrayList(Collection<T> collection) {
        return (ArrayList<T>) list(false, collection);
    }

    /**
     * 新建一个 ArrayList<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param iterable {@link Iterable}
     *
     * @return ArrayList 对象
     */
    public static <T> ArrayList<T> newArrayList(Iterable<T> iterable) {
        return (ArrayList<T>) list(false, iterable);
    }

    /**
     * 新建一个 ArrayList<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param iter {@link Iterator}
     *
     * @return ArrayList 对象
     */
    public static <T> ArrayList<T> newArrayList(Iterator<T> iter) {
        return (ArrayList<T>) list(false, iter);
    }

    /**
     * 新建一个 ArrayList<br>
     * 提供的参数为 null 时返回空 {@link ArrayList}
     *
     * @param <T> 集合元素类型
     * @param enumeration {@link Enumeration}
     *
     * @return ArrayList 对象
     */
    public static <T> ArrayList<T> newArrayList(Enumeration<T> enumeration) {
        return (ArrayList<T>) list(false, enumeration);
    }

    /**
     * 新建 LinkedList
     *
     * @param values 数组
     * @param <T> 类型
     *
     * @return LinkedList
     */
    @SafeVarargs
    public static <T> LinkedList<T> newLinkedList(T... values) {
        return (LinkedList<T>) list(true, values);
    }

    /**
     * 新建一个 CopyOnWriteArrayList
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     *
     * @return {@link CopyOnWriteArrayList}
     */
    public static <T> CopyOnWriteArrayList<T> newCopyOnWriteArrayList(Collection<T> collection) {
        return (null == collection) ? (new CopyOnWriteArrayList<>()) : (new CopyOnWriteArrayList<>(collection));
    }

    /**
     * 新建 {@link BlockingQueue}<br>
     * 在队列为空时，获取元素的线程会等待队列变为非空。当队列满时，存储元素的线程会等待队列可用。
     *
     * @param <T> 集合类型
     * @param capacity 容量
     * @param isLinked 是否为链表形式
     *
     * @return {@link BlockingQueue}
     */
    public static <T> BlockingQueue<T> newBlockingQueue(int capacity, boolean isLinked) {
        BlockingQueue<T> queue;
        if (isLinked) {
            queue = new LinkedBlockingDeque<>(capacity);
        } else {
            queue = new ArrayBlockingQueue<>(capacity);
        }
        return queue;
    }

    /**
     * 创建新的集合对象
     *
     * @param <T> 集合类型
     * @param collectionType 集合类型
     *
     * @return 集合类型对应的实例
     */

    public static <T> Collection<T> create(Class<?> collectionType) {
        Collection<T> list;
        if (collectionType.isAssignableFrom(AbstractCollection.class)) {
            // 抽象集合默认使用 ArrayList
            list = new ArrayList<>();
        }

        // Set
        else if (collectionType.isAssignableFrom(HashSet.class)) {
            list = new HashSet<>();
        } else if (collectionType.isAssignableFrom(LinkedHashSet.class)) {
            list = new LinkedHashSet<>();
        } else if (collectionType.isAssignableFrom(TreeSet.class)) {
            //noinspection SortedCollectionWithNonComparableKeys
            list = new TreeSet<>();
        } else if (collectionType.isAssignableFrom(EnumSet.class)) {
            list = (Collection<T>) EnumSet.noneOf((Class<Enum>) ClassUtils.getTypeArgument(collectionType));
        }

        // List
        else if (collectionType.isAssignableFrom(ArrayList.class)) {
            list = new ArrayList<>();
        } else if (collectionType.isAssignableFrom(LinkedList.class)) {
            list = new LinkedList<>();
        }

        // Others，直接实例化
        else {
            try {
                list = (Collection<T>) ReflectUtils.newInstance(collectionType);
            } catch (Exception e) {
                throw new UtilsException(e);
            }
        }
        return list;
    }

    /**
     * 创建 Map<br>
     * 传入抽象 Map{@link AbstractMap} 和 {@link Map} 类将默认创建 {@link HashMap}
     *
     * @param <K> map 键类型
     * @param <V> map 值类型
     * @param mapType map 类型
     *
     * @return {@link Map} 实例
     *
     * @see MapUtils#createMap(Class)
     */
    public static <K, V> Map<K, V> createMap(Class<?> mapType) {
        return MapUtils.createMap(mapType);
    }

    /**
     * 去重集合
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     *
     * @return {@link ArrayList}
     */
    public static <T> ArrayList<T> distinct(Collection<T> collection) {
        if (isEmpty(collection)) {
            return new ArrayList<>();
        } else if (collection instanceof Set) {
            return new ArrayList<>(collection);
        } else {
            return new ArrayList<>(new LinkedHashSet<>(collection));
        }
    }

    /**
     * 截取集合的部分
     *
     * @param <T> 集合元素类型
     * @param list 被截取的数组
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     *
     * @return 截取后的数组，当开始位置超过最大时，返回空的 List
     */
    public static <T> List<T> sub(List<T> list, int start, int end) {
        return sub(list, start, end, 1);
    }

    /**
     * 截取集合的部分
     *
     * @param <T> 集合元素类型
     * @param list 被截取的数组
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     * @param step 步进
     *
     * @return 截取后的数组，当开始位置超过最大时，返回空的 List
     */
    public static <T> List<T> sub(List<T> list, int start, int end, int step) {
        if (list == null) {
            return null;
        }

        if (list.isEmpty()) {
            return new ArrayList<>(0);
        }

        final int size = list.size();
        if (start < 0) {
            start += size;
        }
        if (end < 0) {
            end += size;
        }
        if (start == size) {
            return new ArrayList<>(0);
        }
        if (start > end) {
            int tmp = start;
            start = end;
            end = tmp;
        }
        if (end > size) {
            if (start >= size) {
                return new ArrayList<>(0);
            }
            end = size;
        }

        if (step <= 1) {
            return list.subList(start, end);
        }

        final List<T> result = new ArrayList<>();
        for (int i = start; i < end; i += step) {
            result.add(list.get(i));
        }
        return result;
    }

    /**
     * 截取集合的部分
     *
     * @param <T> 集合元素类型
     * @param collection 被截取的数组
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     *
     * @return 截取后的数组，当开始位置超过最大时，返回 null
     */
    public static <T> List<T> sub(Collection<T> collection, int start, int end) {
        return sub(collection, start, end, 1);
    }

    /**
     * 截取集合的部分
     *
     * @param <T> 集合元素类型
     * @param list 被截取的数组
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     * @param step 步进
     *
     * @return 截取后的数组，当开始位置超过最大时，返回空集合
     */
    public static <T> List<T> sub(Collection<T> list, int start, int end, int step) {
        if (list == null || list.isEmpty()) {
            return null;
        }

        return sub(new ArrayList<>(list), start, end, step);
    }

    /**
     * 对集合按照指定长度分段，每一个段为单独的集合，返回这个集合的列表
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param size 每个段的长度
     *
     * @return 分段列表
     */
    public static <T> List<List<T>> split(Collection<T> collection, int size) {
        final List<List<T>> result = new ArrayList<>();

        ArrayList<T> subList = new ArrayList<>(size);
        for (T t : collection) {
            if (subList.size() >= size) {
                result.add(subList);
                subList = new ArrayList<>(size);
            }
            subList.add(t);
        }
        result.add(subList);
        return result;
    }

    /**
     * 过滤，此方法产生一个新集合<br>
     * 过滤过程通过传入的 Editor 实现来返回需要的元素内容，这个 Editor 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，如果返回 null 表示这个元素对象抛弃
     * 2、修改元素对象，返回集合中为修改后的对象
     * </pre>
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param editor 编辑器接口
     *
     * @return 过滤后的集合
     */
    public static <T> Collection<T> filter(Collection<T> collection, Editor<T> editor) {
        if (null == collection || null == editor) {
            return collection;
        }

        Collection<T> collection2 = ObjectUtils.clone(collection);
        try {
            collection2.clear();
        } catch (UnsupportedOperationException e) {
            // 克隆后的对象不支持清空，说明为不可变集合对象，使用默认的 ArrayList 保存结果
            collection2 = new ArrayList<>();
        }

        T modified;
        for (T t : collection) {
            modified = editor.edit(t);
            if (null != modified) {
                collection2.add(modified);
            }
        }
        return collection2;
    }

    /**
     * 过滤<br>
     * 过滤过程通过传入的 Editor 实现来返回需要的元素内容，这个 Editor 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，如果返回 null 表示这个元素对象抛弃
     * 2、修改元素对象，返回集合中为修改后的对象
     * </pre>
     *
     * @param <T> 集合元素类型
     * @param list 集合
     * @param editor 编辑器接口
     *
     * @return 过滤后的数组
     */
    public static <T> List<T> filter(List<T> list, Editor<T> editor) {
        if (null == list || null == editor) {
            return list;
        }

        final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
        T modified;
        for (T t : list) {
            modified = editor.edit(t);
            if (null != modified) {
                list2.add(modified);
            }
        }
        return list2;
    }

    /**
     * 过滤<br>
     * 过滤过程通过传入的 Filter 实现来过滤返回需要的元素内容，这个 Filter 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，{@link Filter#accept(Object)} 方法返回 true 的对象将被加入结果集合中
     * </pre>
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param filter 过滤器
     *
     * @return 过滤后的数组
     */
    public static <T> Collection<T> filterNew(Collection<T> collection, Filter<T> filter) {
        if (null == collection || null == filter) {
            return collection;
        }

        Collection<T> collection2 = ObjectUtils.clone(collection);
        try {
            collection2.clear();
        } catch (UnsupportedOperationException e) {
            // 克隆后的对象不支持清空，说明为不可变集合对象，使用默认的 ArrayList 保存结果
            collection2 = new ArrayList<>();
        }

        for (T t : collection) {
            if (filter.accept(t)) {
                collection2.add(t);
            }
        }
        return collection2;
    }

    /**
     * 过滤<br>
     * 过滤过程通过传入的 Filter 实现来过滤返回需要的元素内容，这个 Filter 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，{@link Filter#accept(Object)} 方法返回 true 的对象将被加入结果集合中
     * </pre>
     *
     * @param <T> 集合元素类型
     * @param list 集合
     * @param filter 过滤器
     *
     * @return 过滤后的数组
     */
    public static <T> List<T> filterNew(List<T> list, Filter<T> filter) {
        if (null == list || null == filter) {
            return list;
        }
        final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
        for (T t : list) {
            if (filter.accept(t)) {
                list2.add(t);
            }
        }
        return list2;
    }

    /**
     * 去掉集合中的多个元素，此方法直接修改原集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     * @param elementsRemoved 被去掉的元素数组
     *
     * @return 原集合
     */
    public static <T extends Collection<E>, E> T removeAny(T collection, E... elementsRemoved) {
        collection.removeAll(newHashSet(elementsRemoved));
        return collection;
    }

    /**
     * 去除指定元素，此方法直接修改原集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     * @param filter 过滤器
     *
     * @return 处理后的集合
     */
    public static <T extends Collection<E>, E> T filter(T collection, final Filter<E> filter) {
        return IterUtils.filter(collection, filter);
    }

    /**
     * 去除 {@code null} 元素，此方法直接修改原集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     *
     * @return 处理后的集合
     */
    public static <T extends Collection<E>, E> T removeNull(T collection) {
        return filter(collection, Objects::nonNull);
    }

    /**
     * 去除 {@code null} 或者"" 元素，此方法直接修改原集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     *
     * @return 处理后的集合
     */
    public static <T extends Collection<E>, E extends CharSequence> T removeEmpty(T collection) {
        return filter(collection, StringUtils::isNotEmpty);
    }

    /**
     * 去除 {@code null} 或者""或者空白字符串 元素，此方法直接修改原集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     *
     * @return 处理后的集合
     */
    public static <T extends Collection<E>, E extends CharSequence> T removeBlank(T collection) {
        return filter(collection, StringUtils::isNotBlank);
    }

    /**
     * 通过 Editor 抽取集合元素中的某些值返回为新列表<br>
     * 例如提供的是一个 Bean 列表，通过 Editor 接口实现获取某个字段值，返回这个字段值组成的新列表
     *
     * @param collection 原集合
     * @param editor 编辑器
     *
     * @return 抽取后的新列表
     */
    public static List<Object> extract(Iterable<?> collection, Editor<Object> editor) {
        return extract(collection, editor, false);
    }

    /**
     * 通过 Editor 抽取集合元素中的某些值返回为新列表<br>
     * 例如提供的是一个 Bean 列表，通过 Editor 接口实现获取某个字段值，返回这个字段值组成的新列表
     *
     * @param collection 原集合
     * @param editor 编辑器
     * @param ignoreNull 是否忽略空值
     *
     * @return 抽取后的新列表
     */
    public static List<Object> extract(Iterable<?> collection, Editor<Object> editor, boolean ignoreNull) {
        final List<Object> fieldValueList = new ArrayList<>();
        if (null == collection) {
            return fieldValueList;
        }

        Object value;
        for (Object bean : collection) {
            value = editor.edit(bean);
            if (null == value && ignoreNull) {
                continue;
            }
            fieldValueList.add(value);
        }
        return fieldValueList;
    }

    /**
     * 获取给定 Bean 列表中指定字段名对应字段值的列表<br>
     * 列表元素支持 Bean 与 Map
     *
     * @param collection Bean 集合或 Map 集合
     * @param fieldName 字段名或 map 的键
     *
     * @return 字段值列表
     */
    public static List<Object> getFieldValues(Iterable<?> collection, final String fieldName) {
        return getFieldValues(collection, fieldName, false);
    }

    /**
     * 获取给定 Bean 列表中指定字段名对应字段值的列表<br>
     * 列表元素支持 Bean 与 Map
     *
     * @param collection Bean 集合或 Map 集合
     * @param fieldName 字段名或 map 的键
     * @param ignoreNull 是否忽略值为 {@code null} 的字段
     *
     * @return 字段值列表
     */
    public static List<Object> getFieldValues(Iterable<?> collection, final String fieldName, boolean ignoreNull) {
        return extract(collection, bean -> {
            if (bean instanceof Map) {
                return ((Map<?, ?>) bean).get(fieldName);
            } else {
                return ReflectUtils.getFieldValue(bean, fieldName);
            }
        }, ignoreNull);
    }

    /**
     * 获取给定 Bean 列表中指定字段名对应字段值的列表<br>
     * 列表元素支持 Bean 与 Map
     *
     * @param <T> 元素类型
     * @param collection Bean 集合或 Map 集合
     * @param fieldName 字段名或 map 的键
     * @param elementType 元素类型类
     *
     * @return 字段值列表
     */
    public static <T> List<T> getFieldValues(Iterable<?> collection, final String fieldName, final Class<T> elementType) {
        List<Object> fieldValues = getFieldValues(collection, fieldName);
        return Convert.toList(elementType, fieldValues);
    }

    /**
     * 查找第一个匹配元素对象
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param filter 过滤器，满足过滤条件的第一个元素将被返回
     *
     * @return 满足过滤条件的第一个元素
     */
    public static <T> T findOne(Iterable<T> collection, Filter<T> filter) {
        if (null != collection) {
            for (T t : collection) {
                if (filter.accept(t)) {
                    return t;
                }
            }
        }
        return null;
    }

    /**
     * 查找第一个匹配元素对象<br>
     * 如果集合元素是 Map，则比对键和值是否相同，相同则返回<br>
     * 如果为普通 Bean，则通过反射比对元素字段名对应的字段值是否相同，相同则返回<br>
     * 如果给定字段值参数是 {@code null} 且元素对象中的字段值也为 {@code null} 则认为相同
     *
     * @param <T> 集合元素类型
     * @param collection 集合，集合元素可以是 Bean 或者 Map
     * @param fieldName 集合元素对象的字段名或 map 的键
     * @param fieldValue 集合元素对象的字段值或 map 的值
     *
     * @return 满足条件的第一个元素
     */
    public static <T> T findOneByField(Iterable<T> collection, final String fieldName, final Object fieldValue) {
        return findOne(collection, t -> {
            if (t instanceof Map) {
                final Map<?, ?> map = (Map<?, ?>) t;
                final Object value = map.get(fieldName);
                return ObjectUtils.equal(value, fieldValue);
            }

            // 普通 Bean
            final Object value = ReflectUtils.getFieldValue(t, fieldName);
            return ObjectUtils.equal(value, fieldValue);
        });
    }

    /**
     * 过滤<br>
     * 过滤过程通过传入的 Editor 实现来返回需要的元素内容，这个 Editor 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，如果返回 null 表示这个元素对象抛弃
     * 2、修改元素对象，返回集合中为修改后的对象
     * </pre>
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     * @param map Map
     * @param editor 编辑器接口
     *
     * @return 过滤后的 Map
     *
     * @see MapUtils#filter(Map, Editor)
     */
    public static <K, V> Map<K, V> filter(Map<K, V> map, Editor<Entry<K, V>> editor) {
        return MapUtils.filter(map, editor);
    }

    /**
     * 过滤<br>
     * 过滤过程通过传入的 Editor 实现来返回需要的元素内容，这个 Editor 实现可以实现以下功能：
     *
     * <pre>
     * 1、过滤出需要的对象，如果返回 null 表示这个元素对象抛弃
     * 2、修改元素对象，返回集合中为修改后的对象
     * </pre>
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     * @param map Map
     * @param filter 编辑器接口
     *
     * @return 过滤后的 Map
     *
     * @see MapUtils#filter(Map, Filter)
     */
    public static <K, V> Map<K, V> filter(Map<K, V> map, Filter<Entry<K, V>> filter) {
        return MapUtils.filter(map, filter);
    }

    /**
     * 集合中匹配规则的数量
     *
     * @param <T> 集合元素类型
     * @param iterable {@link Iterable}
     * @param matcher 匹配器，为空则全部匹配
     *
     * @return 匹配数量
     */
    public static <T> int count(Iterable<T> iterable, Matcher<T> matcher) {
        int count = 0;
        if (null != iterable) {
            for (T t : iterable) {
                if (null == matcher || matcher.match(t)) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 集合是否为空
     *
     * @param collection 集合
     *
     * @return 是否为空
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 如果给定集合为空，返回默认集合
     *
     * @param <T> 集合类型
     * @param <E> 集合元素类型
     * @param collection 集合
     * @param defaultCollection 默认数组
     *
     * @return 非空（empty）的原集合或默认集合
     */
    public static <T extends Collection<E>, E> T defaultIfEmpty(T collection, T defaultCollection) {
        return isEmpty(collection) ? defaultCollection : collection;
    }

    /**
     * Map 是否为空
     *
     * @param map 集合
     *
     * @return 是否为空
     *
     * @see MapUtils#isEmpty(Map)
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return MapUtils.isEmpty(map);
    }

    /**
     * Iterable 是否为空
     *
     * @param iterable Iterable 对象
     *
     * @return 是否为空
     *
     * @see IterUtils#isEmpty(Iterable)
     */
    public static boolean isEmpty(Iterable<?> iterable) {
        return IterUtils.isEmpty(iterable);
    }

    /**
     * Iterator 是否为空
     *
     * @param Iterator Iterator 对象
     *
     * @return 是否为空
     *
     * @see IterUtils#isEmpty(Iterator)
     */
    public static boolean isEmpty(Iterator<?> Iterator) {
        return IterUtils.isEmpty(Iterator);
    }

    /**
     * Enumeration 是否为空
     *
     * @param enumeration {@link Enumeration}
     *
     * @return 是否为空
     */
    public static boolean isEmpty(Enumeration<?> enumeration) {
        return null == enumeration || !enumeration.hasMoreElements();
    }

    /**
     * 集合是否为非空
     *
     * @param collection 集合
     *
     * @return 是否为非空
     */
    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    /**
     * Map 是否为非空
     *
     * @param map 集合
     *
     * @return 是否为非空
     *
     * @see MapUtils#isNotEmpty(Map)
     */
    public static boolean isNotEmpty(Map<?, ?> map) {
        return MapUtils.isNotEmpty(map);
    }

    /**
     * Iterable 是否为空
     *
     * @param iterable Iterable 对象
     *
     * @return 是否为空
     *
     * @see IterUtils#isNotEmpty(Iterable)
     */
    public static boolean isNotEmpty(Iterable<?> iterable) {
        return IterUtils.isNotEmpty(iterable);
    }

    /**
     * Iterator 是否为空
     *
     * @param Iterator Iterator 对象
     *
     * @return 是否为空
     *
     * @see IterUtils#isNotEmpty(Iterator)
     */
    public static boolean isNotEmpty(Iterator<?> Iterator) {
        return IterUtils.isNotEmpty(Iterator);
    }

    /**
     * Enumeration 是否为空
     *
     * @param enumeration {@link Enumeration}
     *
     * @return 是否为空
     */
    public static boolean isNotEmpty(Enumeration<?> enumeration) {
        return null != enumeration && enumeration.hasMoreElements();
    }

    /**
     * 是否包含 {@code null} 元素
     *
     * @param iterable 被检查的 Iterable 对象，如果为 {@code null} 返回 false
     *
     * @return 是否包含 {@code null} 元素
     *
     * @see IterUtils#hasNull(Iterable)
     */
    public static boolean hasNull(Iterable<?> iterable) {
        return IterUtils.hasNull(iterable);
    }

    /**
     * 映射键值（参考 Python 的 zip()函数）<br>
     * 例如：<br>
     * keys = a,b,c,d<br>
     * values = 1,2,3,4<br>
     * delimiter = , 则得到的 Map 是 {a=1, b=2, c=3, d=4}<br>
     * 如果两个数组长度不同，则只对应最短部分
     *
     * @param keys 键列表
     * @param values 值列表
     * @param delimiter 分隔符
     * @param isOrder 是否有序
     *
     * @return Map
     */
    public static Map<String, String> zip(String keys, String values, String delimiter, boolean isOrder) {
        return ArrayUtils.zip(StringUtils.split(keys, delimiter), StringUtils.split(values, delimiter), isOrder);
    }

    /**
     * 映射键值（参考 Python 的 zip()函数），返回 Map 无序<br>
     * 例如：<br>
     * keys = a,b,c,d<br>
     * values = 1,2,3,4<br>
     * delimiter = , 则得到的 Map 是 {a=1, b=2, c=3, d=4}<br>
     * 如果两个数组长度不同，则只对应最短部分
     *
     * @param keys 键列表
     * @param values 值列表
     * @param delimiter 分隔符
     *
     * @return Map
     */
    public static Map<String, String> zip(String keys, String values, String delimiter) {
        return zip(keys, values, delimiter, false);
    }

    /**
     * 映射键值（参考 Python 的 zip()函数）<br>
     * 例如：<br>
     * keys = [a,b,c,d]<br>
     * values = [1,2,3,4]<br>
     * 则得到的 Map 是 {a=1, b=2, c=3, d=4}<br>
     * 如果两个数组长度不同，则只对应最短部分
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param keys 键列表
     * @param values 值列表
     *
     * @return Map
     */
    public static <K, V> Map<K, V> zip(Collection<K> keys, Collection<V> values) {
        if (isEmpty(keys) || isEmpty(values)) {
            return null;
        }

        int entryCount = Math.min(keys.size(), values.size());
        final Map<K, V> map = newHashMap(entryCount);

        final Iterator<K> keyIterator = keys.iterator();
        final Iterator<V> valueIterator = values.iterator();
        while (entryCount > 0) {
            map.put(keyIterator.next(), valueIterator.next());
            entryCount--;
        }

        return map;
    }

    /**
     * 将 Entry 集合转换为 HashMap
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param entryIter entry 集合
     *
     * @return Map
     *
     * @see IterUtils#toMap(Iterable)
     */
    public static <K, V> HashMap<K, V> toMap(Iterable<Entry<K, V>> entryIter) {
        return IterUtils.toMap(entryIter);
    }

    /**
     * 将数组转换为 Map（HashMap），支持数组元素类型为：
     *
     * <pre>
     * Map.Entry
     * 长度大于 1 的数组（取前两个值），如果不满足跳过此元素
     * Iterable 长度也必须大于 1（取前两个值），如果不满足跳过此元素
     * Iterator 长度也必须大于 1（取前两个值），如果不满足跳过此元素
     * </pre>
     *
     * <pre>
     * Map&lt;Object, Object&gt; colorMap = CollectionUtil.toMap(new String[][] {{
     *     {"RED", "#FF0000"},
     *     {"GREEN", "#00FF00"},
     *     {"BLUE", "#0000FF"}});
     * </pre>
     * <p>
     * 参考：commons-lang
     *
     * @param array 数组。元素类型为 Map.Entry、数组、Iterable、Iterator
     *
     * @return {@link HashMap}
     *
     * @see MapUtils#of(Object[])
     */
    public static HashMap<Object, Object> toMap(Object[] array) {
        return MapUtils.of(array);
    }

    /**
     * 将集合转换为排序后的 TreeSet
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param comparator 比较器
     *
     * @return treeSet
     */
    public static <T> TreeSet<T> toTreeSet(Collection<T> collection, Comparator<T> comparator) {
        final TreeSet<T> treeSet = new TreeSet<>(comparator);
        treeSet.addAll(collection);
        return treeSet;
    }

    /**
     * Iterator 转换为 Enumeration
     * <p>
     * Adapt the specified <code>Iterator</code> to the <code>Enumeration</code> interface.
     *
     * @param <E> 集合元素类型
     * @param iter {@link Iterator}
     *
     * @return {@link Enumeration}
     */
    public static <E> Enumeration<E> asEnumeration(Iterator<E> iter) {
        return new IteratorEnumeration<>(iter);
    }

    /**
     * Enumeration 转换为 Iterator
     * <p>
     * Adapt the specified <code>Enumeration</code> to the <code>Iterator</code> interface
     *
     * @param <E> 集合元素类型
     * @param e {@link Enumeration}
     *
     * @return {@link Iterator}
     *
     * @see IterUtils#asIterator(Enumeration)
     */
    public static <E> Iterator<E> asIterator(Enumeration<E> e) {
        return IterUtils.asIterator(e);
    }

    /**
     * {@link Iterator} 转为 {@link Iterable}
     *
     * @param <E> 元素类型
     * @param iter {@link Iterator}
     *
     * @return {@link Iterable}
     *
     * @see IterUtils#asIterable(Iterator)
     */
    public static <E> Iterable<E> asIterable(final Iterator<E> iter) {
        return IterUtils.asIterable(iter);
    }

    /**
     * {@link Iterable} 转为 {@link Collection}<br>
     * 首先尝试强转，强转失败则构建一个新的 {@link ArrayList}
     *
     * @param <E> 集合元素类型
     * @param iterable {@link Iterable}
     *
     * @return {@link Collection} 或者 {@link ArrayList}
     */
    public static <E> Collection<E> toCollection(Iterable<E> iterable) {
        return (iterable instanceof Collection) ? (Collection<E>) iterable : newArrayList(iterable.iterator());
    }

    /**
     * 行转列，合并相同的键，值合并为列表<br>
     * 将 Map 列表中相同 key 的值组成列表做为 Map 的 value<br>
     * 是 {@link #toMapList(Map)} 的逆方法<br>
     * 比如传入数据：
     *
     * <pre>
     * [
     *  {a: 1, b: 1, c: 1}
     *  {a: 2, b: 2}
     *  {a: 3, b: 3}
     *  {a: 4}
     * ]
     * </pre>
     * <p>
     * 结果是：
     *
     * <pre>
     * {
     *   a: [1,2,3,4]
     *   b: [1,2,3,]
     *   c: [1]
     * }
     * </pre>
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param mapList Map 列表
     *
     * @return Map
     *
     * @see MapUtils#toListMap(Iterable)
     */
    public static <K, V> Map<K, List<V>> toListMap(Iterable<? extends Map<K, V>> mapList) {
        return MapUtils.toListMap(mapList);
    }

    /**
     * 列转行。将 Map 中值列表分别按照其位置与 key 组成新的 map。<br>
     * 是 {@link #toListMap(Iterable)} 的逆方法<br>
     * 比如传入数据：
     *
     * <pre>
     * {
     *   a: [1,2,3,4]
     *   b: [1,2,3,]
     *   c: [1]
     * }
     * </pre>
     * <p>
     * 结果是：
     *
     * <pre>
     * [
     *  {a: 1, b: 1, c: 1}
     *  {a: 2, b: 2}
     *  {a: 3, b: 3}
     *  {a: 4}
     * ]
     * </pre>
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param listMap 列表 Map
     *
     * @return Map 列表
     *
     * @see MapUtils#toMapList(Map)
     */
    public static <K, V> List<Map<K, V>> toMapList(Map<K, ? extends Iterable<V>> listMap) {
        return MapUtils.toMapList(listMap);
    }

    /**
     * 将指定对象全部加入到集合中<br>
     * 提供的对象如果为集合类型，会自动转换为目标元素类型<br>
     *
     * @param <T> 元素类型
     * @param collection 被加入的集合
     * @param value 对象，可能为 Iterator、Iterable、Enumeration、Array
     *
     * @return 被加入集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, Object value) {
        return addAll(collection, value, TypeUtils.getTypeArgument(collection.getClass()));
    }

    /**
     * 将指定对象全部加入到集合中<br>
     * 提供的对象如果为集合类型，会自动转换为目标元素类型<br>
     * 如果为 String，支持类似于[1,2,3,4] 或者 1,2,3,4 这种格式
     *
     * @param <T> 元素类型
     * @param collection 被加入的集合
     * @param value 对象，可能为 Iterator、Iterable、Enumeration、Array，或者与集合元素类型一致
     * @param elementType 元素类型，为空时，使用 Object 类型来接纳所有类型
     *
     * @return 被加入集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, Object value, Type elementType) {
        if (null == collection || null == value) {
            return collection;
        }
        if (TypeUtils.isUnknown(elementType)) {
            // 元素类型为空时，使用 Object 类型来接纳所有类型
            elementType = Object.class;
        }

        Iterator iter;
        if (value instanceof Iterator) {
            iter = (Iterator) value;
        } else if (value instanceof Iterable) {
            iter = ((Iterable) value).iterator();
        } else if (value instanceof Enumeration) {
            iter = new EnumerationIter<>((Enumeration) value);
        } else if (ArrayUtils.isArray(value)) {
            iter = new ArrayIter<>(value);
        } else if (value instanceof CharSequence) {
            // String 按照逗号分隔的列表对待
            final String ArrayStr = StringUtils.unWrap((CharSequence) value, '[', ']');
            iter = StringUtils.splitTrim(ArrayStr, CharUtils.COMMA).iterator();
        } else {
            // 其它类型按照单一元素处理
            iter = CollectionUtils.newArrayList(value).iterator();
        }

        final ConverterRegistry convert = ConverterRegistry.getInstance();
        while (iter.hasNext()) {
            collection.add(convert.convert(elementType, iter.next()));
        }

        return collection;
    }

    /**
     * 加入全部
     *
     * @param <T> 集合元素类型
     * @param collection 被加入的集合 {@link Collection}
     * @param iterator 要加入的 {@link Iterator}
     *
     * @return 原集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, Iterator<T> iterator) {
        if (null != collection && null != iterator) {
            while (iterator.hasNext()) {
                collection.add(iterator.next());
            }
        }
        return collection;
    }

    /**
     * 加入全部
     *
     * @param <T> 集合元素类型
     * @param collection 被加入的集合 {@link Collection}
     * @param iterable 要加入的内容 {@link Iterable}
     *
     * @return 原集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, Iterable<T> iterable) {
        return addAll(collection, iterable.iterator());
    }

    /**
     * 加入全部
     *
     * @param <T> 集合元素类型
     * @param collection 被加入的集合 {@link Collection}
     * @param enumeration 要加入的内容 {@link Enumeration}
     *
     * @return 原集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, Enumeration<T> enumeration) {
        if (null != collection && null != enumeration) {
            while (enumeration.hasMoreElements()) {
                collection.add(enumeration.nextElement());
            }
        }
        return collection;
    }

    /**
     * 加入全部
     *
     * @param <T> 集合元素类型
     * @param collection 被加入的集合 {@link Collection}
     * @param values 要加入的内容数组
     *
     * @return 原集合
     */
    public static <T> Collection<T> addAll(Collection<T> collection, T[] values) {
        if (null != collection && null != values) {
            Collections.addAll(collection, values);
        }
        return collection;
    }

    /**
     * 将另一个列表中的元素加入到列表中，如果列表中已经存在此元素则忽略之
     *
     * @param <T> 集合元素类型
     * @param list 列表
     * @param otherList 其它列表
     *
     * @return 此列表
     */
    public static <T> List<T> addAllIfNotContains(List<T> list, List<T> otherList) {
        for (T t : otherList) {
            if (!list.contains(t)) {
                list.add(t);
            }
        }
        return list;
    }

    /**
     * 获取集合中指定下标的元素值，下标可以为负数，例如-1 表示最后一个元素<br>
     * 如果元素越界，返回 null
     *
     * @param <T> 元素类型
     * @param collection 集合
     * @param index 下标，支持负数
     *
     * @return 元素值
     */
    public static <T> T get(Collection<T> collection, int index) {
        if (null == collection) {
            return null;
        }

        final int size = collection.size();
        if (0 == size) {
            return null;
        }

        if (index < 0) {
            index += size;
        }

        // 检查越界
        if (index >= size) {
            return null;
        }

        if (collection instanceof List) {
            final List<T> list = ((List<T>) collection);
            return list.get(index);
        } else {
            int i = 0;
            for (T t : collection) {
                if (i > index) {
                    break;
                } else if (i == index) {
                    return t;
                }
                i++;
            }
        }
        return null;
    }

    /**
     * 获取集合中指定多个下标的元素值，下标可以为负数，例如-1 表示最后一个元素
     *
     * @param <T> 元素类型
     * @param collection 集合
     * @param indexes 下标，支持负数
     *
     * @return 元素值列表
     */
    public static <T> List<T> getAny(Collection<T> collection, int... indexes) {
        final int size = collection.size();
        final ArrayList<T> result = new ArrayList<>();
        if (collection instanceof List) {
            final List<T> list = ((List<T>) collection);
            for (int index : indexes) {
                if (index < 0) {
                    index += size;
                }
                result.add(list.get(index));
            }
        } else {
            final Object[] array = collection.toArray();
            for (int index : indexes) {
                if (index < 0) {
                    index += size;
                }
                result.add((T) array[index]);
            }
        }
        return result;
    }

    /**
     * 获取集合的第一个元素
     *
     * @param <T> 集合元素类型
     * @param iterable {@link Iterable}
     *
     * @return 第一个元素
     *
     * @see IterUtils#getFirst(Iterable)
     */
    public static <T> T getFirst(Iterable<T> iterable) {
        return IterUtils.getFirst(iterable);
    }

    /**
     * 获取集合的第一个元素
     *
     * @param <T> 集合元素类型
     * @param iterator {@link Iterator}
     *
     * @return 第一个元素
     *
     * @see IterUtils#getFirst(Iterator)
     */
    public static <T> T getFirst(Iterator<T> iterator) {
        return IterUtils.getFirst(iterator);
    }

    /**
     * 获取集合的最后一个元素
     *
     * @param <T> 集合元素类型
     * @param collection {@link Collection}
     *
     * @return 最后一个元素
     */
    public static <T> T getLast(Collection<T> collection) {
        return get(collection, -1);
    }

    /**
     * 获得 {@link Iterable} 对象的元素类型（通过第一个非空元素判断）
     *
     * @param iterable {@link Iterable}
     *
     * @return 元素类型，当列表为空或元素全部为 null 时，返回 null
     *
     * @see IterUtils#getElementType(Iterable)
     */
    public static Class<?> getElementType(Iterable<?> iterable) {
        return IterUtils.getElementType(iterable);
    }

    /**
     * 获得 {@link Iterator} 对象的元素类型（通过第一个非空元素判断）
     *
     * @param iterator {@link Iterator}
     *
     * @return 元素类型，当列表为空或元素全部为 null 时，返回 null
     *
     * @see IterUtils#getElementType(Iterator)
     */
    public static Class<?> getElementType(Iterator<?> iterator) {
        return IterUtils.getElementType(iterator);
    }

    /**
     * 从 Map 中获取指定键列表对应的值列表<br>
     * 如果 key 在 map 中不存在或 key 对应值为 null，则返回值列表对应位置的值也为 null
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param map {@link Map}
     * @param keys 键列表
     *
     * @return 值列表
     */
    public static <K, V> ArrayList<V> valuesOfKeys(Map<K, V> map, K... keys) {
        final ArrayList<V> values = new ArrayList<>();
        for (K k : keys) {
            values.add(map.get(k));
        }
        return values;
    }

    /**
     * 从 Map 中获取指定键列表对应的值列表<br>
     * 如果 key 在 map 中不存在或 key 对应值为 null，则返回值列表对应位置的值也为 null
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param map {@link Map}
     * @param keys 键列表
     *
     * @return 值列表
     */
    public static <K, V> ArrayList<V> valuesOfKeys(Map<K, V> map, Iterable<K> keys) {
        return valuesOfKeys(map, keys.iterator());
    }

    /**
     * 从 Map 中获取指定键列表对应的值列表<br>
     * 如果 key 在 map 中不存在或 key 对应值为 null，则返回值列表对应位置的值也为 null
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param map {@link Map}
     * @param keys 键列表
     *
     * @return 值列表
     */
    public static <K, V> ArrayList<V> valuesOfKeys(Map<K, V> map, Iterator<K> keys) {
        final ArrayList<V> values = new ArrayList<>();
        while (keys.hasNext()) {
            values.add(map.get(keys.next()));
        }
        return values;
    }

    /**
     * 将多个集合排序并显示不同的段落（分页）<br>
     * 采用 {@link BoundedPriorityQueue} 实现分页取局部
     *
     * @param <T> 集合元素类型
     * @param pageNo 页码，从 1 开始计数，0 和 1 效果相同
     * @param pageSize 每页的条目数
     * @param comparator 比较器
     * @param colls 集合数组
     *
     * @return 分页后的段落内容
     */
    @SafeVarargs
    public static <T> List<T> sortPageAll(int pageNo, int pageSize, Comparator<T> comparator, Collection<T>... colls) {
        final List<T> list = new ArrayList<>(pageNo * pageSize);
        for (Collection<T> coll : colls) {
            list.addAll(coll);
        }
        if (null != comparator) {
            list.sort(comparator);
        }

        return page(pageNo, pageSize, list);
    }

    /**
     * 对指定 List 分页取值
     *
     * @param <T> 集合元素类型
     * @param pageNo 页码，从 1 开始计数，0 和 1 效果相同
     * @param pageSize 每页的条目数
     * @param list 列表
     *
     * @return 分页后的段落内容
     */
    public static <T> List<T> page(int pageNo, int pageSize, List<T> list) {
        if (isEmpty(list)) {
            return new ArrayList<>(0);
        }

        int resultSize = list.size();
        // 每页条目数大于总数直接返回所有
        if (resultSize <= pageSize) {
            if (pageNo <= 1) {
                return Collections.unmodifiableList(list);
            } else {
                // 越界直接返回空
                return new ArrayList<>(0);
            }
        }
        final int[] startEnd = PageUtils.transToStartEnd(pageNo, pageSize);
        if (startEnd[1] > resultSize) {
            startEnd[1] = resultSize;
        }
        return list.subList(startEnd[0], startEnd[1]);
    }

    /**
     * 排序集合，排序不会修改原集合
     *
     * @param <T> 集合元素类型
     * @param collection 集合
     * @param comparator 比较器
     *
     * @return treeSet
     */
    public static <T> List<T> sort(Collection<T> collection, Comparator<? super T> comparator) {
        List<T> list = new ArrayList<>(collection);
        list.sort(comparator);
        return list;
    }

    /**
     * 针对 List 排序，排序会修改原 List
     *
     * @param <T> 元素类型
     * @param list 被排序的 List
     * @param c {@link Comparator}
     *
     * @return 原 list
     *
     * @see Collections#sort(List, Comparator)
     */
    public static <T> List<T> sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
        return list;
    }

    /**
     * 根据 Bean 的属性排序
     *
     * @param <T> 元素类型
     * @param collection 集合，会被转换为 List
     * @param property 属性名
     *
     * @return 排序后的 List
     */
    public static <T> List<T> sortByProperty(Collection<T> collection, String property) {
        return sort(collection, new PropertyComparator<>(property));
    }

    /**
     * 根据 Bean 的属性排序
     *
     * @param <T> 元素类型
     * @param list List
     * @param property 属性名
     *
     * @return 排序后的 List
     */
    public static <T> List<T> sortByProperty(List<T> list, String property) {
        return sort(list, new PropertyComparator<>(property));
    }

    /**
     * 根据汉字的拼音顺序排序
     *
     * @param collection 集合，会被转换为 List
     *
     * @return 排序后的 List
     */
    public static List<String> sortByPinyin(Collection<String> collection) {
        return sort(collection, new PinyinComparator());
    }

    /**
     * 根据汉字的拼音顺序排序
     *
     * @param list List
     *
     * @return 排序后的 List
     */
    public static List<String> sortByPinyin(List<String> list) {
        return sort(list, new PinyinComparator());
    }

    /**
     * 排序 Map
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param map Map
     * @param comparator Entry 比较器
     *
     * @return {@link TreeMap}
     */
    public static <K, V> TreeMap<K, V> sort(Map<K, V> map, Comparator<? super K> comparator) {
        final TreeMap<K, V> result = new TreeMap<>(comparator);
        result.putAll(map);
        return result;
    }

    /**
     * 通过 Entry 排序，可以按照键排序，也可以按照值排序，亦或者两者综合排序
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param entryCollection Entry 集合
     * @param comparator {@link Comparator}
     *
     * @return {@link LinkedList}
     */
    public static <K, V> LinkedHashMap<K, V> sortToMap(Collection<Entry<K, V>> entryCollection, Comparator<Entry<K, V>> comparator) {
        List<Entry<K, V>> list = new LinkedList<>(entryCollection);
        list.sort(comparator);

        LinkedHashMap<K, V> result = new LinkedHashMap<>();
        for (Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    /**
     * 通过 Entry 排序，可以按照键排序，也可以按照值排序，亦或者两者综合排序
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param map 被排序的 Map
     * @param comparator {@link Comparator}
     *
     * @return {@link LinkedList}
     */
    public static <K, V> LinkedHashMap<K, V> sortByEntry(Map<K, V> map, Comparator<Entry<K, V>> comparator) {
        return sortToMap(map.entrySet(), comparator);
    }

    /**
     * 将 Set 排序（根据 Entry 的值）
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param collection 被排序的 {@link Collection}
     *
     * @return 排序后的 Set
     */
    public static <K, V> List<Entry<K, V>> sortEntryToList(Collection<Entry<K, V>> collection) {
        List<Entry<K, V>> list = new LinkedList<>(collection);
        list.sort((o1, o2) -> {
            V v1 = o1.getValue();
            V v2 = o2.getValue();

            if (v1 instanceof Comparable) {
                return ((Comparable) v1).compareTo(v2);
            } else {
                return v1.toString().compareTo(v2.toString());
            }
        });
        return list;
    }

    /**
     * 循环遍历 {@link Iterator}，使用 {@link Consumer} 接受遍历的每条数据，并针对每条数据做处理
     *
     * @param <T> 集合元素类型
     * @param iterator {@link Iterator}
     * @param consumer {@link Consumer} 遍历的每条数据处理器
     */
    public static <T> void forEach(Iterator<T> iterator, Consumer<T> consumer) {
        int index = 0;
        while (iterator.hasNext()) {
            consumer.accept(iterator.next(), index);
            index++;
        }
    }

    /**
     * 循环遍历 {@link Enumeration}，使用 {@link Consumer} 接受遍历的每条数据，并针对每条数据做处理
     *
     * @param <T> 集合元素类型
     * @param enumeration {@link Enumeration}
     * @param consumer {@link Consumer} 遍历的每条数据处理器
     */
    public static <T> void forEach(Enumeration<T> enumeration, Consumer<T> consumer) {
        int index = 0;
        while (enumeration.hasMoreElements()) {
            consumer.accept(enumeration.nextElement(), index);
            index++;
        }
    }

    /**
     * 循环遍历 Map，使用 {@link KVConsumer} 接受遍历的每条数据，并针对每条数据做处理
     *
     * @param <K> Key 类型
     * @param <V> Value 类型
     * @param map {@link Map}
     * @param kvConsumer {@link KVConsumer} 遍历的每条数据处理器
     */
    public static <K, V> void forEach(Map<K, V> map, KVConsumer<K, V> kvConsumer) {
        int index = 0;
        for (Entry<K, V> entry : map.entrySet()) {
            kvConsumer.accept(entry.getKey(), entry.getValue(), index);
            index++;
        }
    }

    /**
     * 分组，按照 {@link Hash} 接口定义的 hash 算法，集合中的元素放入 hash 值对应的子列表中
     *
     * @param <T> 元素类型
     * @param collection 被分组的集合
     * @param hash Hash 值算法，决定元素放在第几个分组的规则
     *
     * @return 分组后的集合
     */
    public static <T> List<List<T>> group(Collection<T> collection, Hash<T> hash) {
        final List<List<T>> result = new ArrayList<>();
        if (isEmpty(collection)) {
            return result;
        }
        if (null == hash) {
            // 默认 hash 算法，按照元素的 hashCode 分组
            hash = t -> (null == t) ? 0 : t.hashCode();
        }

        int index;
        List<T> subList;
        for (T t : collection) {
            index = hash.hash(t);
            if (result.size() - 1 < index) {
                while (result.size() - 1 < index) {
                    result.add(null);
                }
                result.set(index, newArrayList(t));
            } else {
                subList = result.get(index);
                if (null == subList) {
                    result.set(index, newArrayList(t));
                } else {
                    subList.add(t);
                }
            }
        }
        return result;
    }

    /**
     * 根据元素的指定字段名分组，非 Bean 都放在第一个分组中
     *
     * @param <T> 元素类型
     * @param collection 集合
     * @param fieldName 元素 Bean 中的字段名，非 Bean 都放在第一个分组中
     *
     * @return 分组列表
     */
    public static <T> List<List<T>> groupByField(Collection<T> collection, final String fieldName) {
        return group(collection, new Hash<T>() {

            private final List<Object> fieldNameList = new ArrayList<>();

            @Override
            public int hash(T t) {
                if (null == t || !BeanUtils.isBean(t.getClass())) {
                    // 非 Bean 放在同一子分组中
                    return 0;
                }
                final Object value = ReflectUtils.getFieldValue(t, fieldName);
                int hash = fieldNameList.indexOf(value);
                if (hash < 0) {
                    fieldNameList.add(value);
                    return fieldNameList.size() - 1;
                } else {
                    return hash;
                }
            }
        });
    }

    /**
     * 反序给定 List，会在原 List 基础上直接修改
     *
     * @param <T> 元素类型
     * @param list 被反转的 List
     *
     * @return 反转后的 List
     */
    public static <T> List<T> reverse(List<T> list) {
        Collections.reverse(list);
        return list;
    }

    /**
     * 反序给定 List，会创建一个新的 List，原 List 数据不变
     *
     * @param <T> 元素类型
     * @param list 被反转的 List
     *
     * @return 反转后的 List
     */
    public static <T> List<T> reverseNew(List<T> list) {
        final List<T> list2 = ObjectUtils.clone(list);
        return reverse(list2);
    }

    /**
     * 设置或增加元素。当 index 小于 List 的长度时，替换指定位置的值，否则在尾部追加
     *
     * @param <T> 元素类型
     * @param list List 列表
     * @param index 位置
     * @param element 新元素
     *
     * @return 原 List
     */
    public static <T> List<T> setOrAppend(List<T> list, int index, T element) {
        if (index < list.size()) {
            list.set(index, element);
        } else {
            list.add(element);
        }
        return list;
    }

    /**
     * 获取指定 Map 列表中所有的 Key
     *
     * @param <K> 键类型
     * @param mapCollection Map 列表
     *
     * @return key 集合
     */
    public static <K> Set<K> keySet(Collection<Map<K, ?>> mapCollection) {
        if (isEmpty(mapCollection)) {
            return new HashSet<>();
        }
        final HashSet<K> set = new HashSet<>(mapCollection.size() * 16);
        for (Map<K, ?> map : mapCollection) {
            set.addAll(map.keySet());
        }

        return set;
    }

    /**
     * 获取指定 Map 列表中所有的 Value
     *
     * @param <V> 值类型
     * @param mapCollection Map 列表
     *
     * @return Value 集合
     */
    public static <V> List<V> values(Collection<Map<?, V>> mapCollection) {
        final List<V> values = new ArrayList<>();
        for (Map<?, V> map : mapCollection) {
            values.addAll(map.values());
        }

        return values;
    }

    /**
     * 取最大值
     *
     * @param <T> 元素类型
     * @param coll 集合
     *
     * @return 最大值
     *
     * @see Collections#max(Collection)
     */
    public static <T extends Comparable<? super T>> T max(Collection<T> coll) {
        return Collections.max(coll);
    }

    /**
     * 取最大值
     *
     * @param <T> 元素类型
     * @param coll 集合
     *
     * @return 最大值
     *
     * @see Collections#min(Collection)
     */
    public static <T extends Comparable<? super T>> T min(Collection<T> coll) {
        return Collections.min(coll);
    }

    /**
     * 针对一个参数做相应的操作
     *
     * @param <T> 处理参数类型
     */
    public interface Consumer<T> {

        /**
         * 接受并处理一个参数
         *
         * @param value 参数值
         * @param index 参数在集合中的索引
         */
        void accept(T value, int index);

    }

    /**
     * 针对两个参数做相应的操作，例如 Map 中的 KEY 和 VALUE
     *
     * @param <K> KEY 类型
     * @param <V> VALUE 类型
     */
    public interface KVConsumer<K, V> {

        /**
         * 接受并处理一对参数
         *
         * @param key 键
         * @param value 值
         * @param index 参数在集合中的索引
         */
        void accept(K key, V value, int index);

    }

    /**
     * Hash 计算接口
     *
     * @param <T> 被计算 hash 的对象类型
     */
    public interface Hash<T> {

        /**
         * 计算 Hash 值
         *
         * @param t 对象
         *
         * @return hash
         */
        int hash(T t);

    }

}
